﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference name="MicrosoftAjaxTemplates.js"/>
// Name:        BatikDataView.debug.js

(function() {

    function execute() {
        Type._registerScript("BatikDataView.js", ["MicrosoftAjaxTemplates.js"]);
        Type.registerNamespace("Batik.UI");
        Batik.UI.DataView = function Batik$UI$DataView(element) {
            Batik.UI.DataView.initializeBase(this, [element]);
            this._editMode = false;
            this._element = element;
            this._viewTemplate = null;
            this._editTemplate = null;
            this._progressTemplate = null;
            this._datasourceID = null;
            this._datasource = null;
            this._enablePaging = true;
            this._pageSize = 10;
            this._currentPageIndex = 0;
            this._currentPageData = [];
            this._allData = null;
        }

        // create private members
        function Batik$UI$DataView$initialize() {
            Batik.UI.DataView.callBaseMethod(this, 'initialize');
            // Add custom initialization here
            this.set_viewTemplate(this.get_itemTemplate());
            var itemTemplate = this.get_itemTemplate();
            var firstChild = itemTemplate.firstChild;
            if (firstChild != 'undifined' && firstChild != null) {
                firstChild.setAttribute('sys:command', 'select');
                firstChild.setAttribute('sys:commandargument', '{{$index}}');
            }
            var editTemplate = this.get_editTemplate();
            var cloneTemplate = editTemplate.cloneNode(999);
            if (editTemplate != 'undefined' && editTemplate != null) {
                var editParent = editTemplate.parentNode;
                var editChild = editTemplate.firstChild;
                editChild.style.display = 'none';
                editChild.style.visibility = 'hidden';
                itemTemplate.appendChild(editChild);
                editParent.removeChild(editTemplate);
                this.set_editTemplate(cloneTemplate);
            }
            this.set_itemTemplate(itemTemplate);
            var _datasource = this.get_datasource();
            if (_datasource) {
                _datasource.selectData();
                _datasource.add_selectCompleted(Function.createDelegate(this, Batik$UI$DataView$_onSelectComplete));
            }
            this.add_itemRendering(Function.createDelegate(this, Batik$UI$DataView$_onItemRendering));
            this.add_rendering(Function.createDelegate(this, Batik$UI$DataView$_onRendering));
            this.add_rendered(Function.createDelegate(this, Batik$UI$DataView$_onRendered));
            this.add_command(Function.createDelegate(this, Batik$UI$DataView$_onCommand));
        }
        function Batik$UI$DataView$dispose() {
            //Add custom dispose actions here
            var _datasource = this.get_datasource();
            if (_datasource) {
                _datasource.remove_selectCompleted(Function.createDelegate(this, Batik$UI$DataView$_onSelectComplete));
            }
            Batik.UI.DataView.callBaseMethod(this, 'dispose');
        }

        function Batik$UI$DataView$set_datasourceID(value) {
            var e = Function._validateParams(arguments, [
                        { name: "value", type: String }
                    ]);
            if (e) throw e;
            this._datasourceID = value;
        }
        function Batik$UI$DataView$get_datasourceID() {
            return this._datasourceID;
        }

        function Batik$UI$DataView$get_datasource() {
            var _datasourceID = this.get_datasourceID();
            if (_datasourceID != 'undefined' && _datasourceID != null) {
                this._datasource = $find(_datasourceID);
            }
            return this._datasource;
        }

        function Batik$UI$DataView$set_viewTemplate(element) {
            var e = Function._validateParams(arguments, [
                        { name: "element", type: Object, mayBeNull: false, optional: false, elementMayBeNull: false }
                    ]);
            if (e) throw e;
            this._viewTemplate = element;
        }
        function Batik$UI$DataView$get_viewTemplate() {
            return this._viewTemplate;
        }

        function Batik$UI$DataView$set_editTemplate(element) {
            var e = Function._validateParams(arguments, [
                        { name: "element", type: Object, mayBeNull: false, optional: false, elementMayBeNull: false }
                    ]);
            if (e) throw e;
            this._editTemplate = element;
        }
        function Batik$UI$DataView$get_editTemplate() {
            return this._editTemplate;
        }

        function Batik$UI$DataView$set_progressTemplate(element) {
            var e = Function._validateParams(arguments, [
                    { name: "element", type: Object, mayBeNull: false, optional: false, elementMayBeNull: false }
                ]);
            if (e) throw e;
            this._progressTemplate = element;
        }
        function Batik$UI$DataView$get_progressTemplate() {
            return this._progressTemplate;
        }

        function Batik$UI$DataView$insert() {
            var newEl = this.get_editTemplate().cloneNode(999);
            var prnNode = this.get_element().parentNode;
            prnNode.appendChild(newEl);
            newEl.id = String.format('{0}_insert_{1}', this.get_id(), Math.floor(Math.random() * 999999));
            var nobj = $create(Sys.UI.DataView,
                    { "autoFetch": true, "data": {}, "id": newEl.id },
                    null, null, newEl);
            nobj.add_command(Function.createDelegate(this, function(s, e) {
                switch (e.get_commandName()) {
                    case 'update':
                        prnNode.removeChild(newEl);
                        Batik$UI$DataView$_showProgress.apply(this, []);
                        // using setTimeout to make sure progress indicator was rendered
                        setTimeout(Function.createDelegate(this, function() {
                            /*var ds = this.get_datasource();
                            if (!!ds) {
                            var dt = ds.get_data();
                            dt.add(nobj.get_data());
                            ds.insertData(nobj.get_data());
                            }
                            nobj = null;*/

                            var dt = this.get_data();
                            if (!!dt) {
                                dt.add(nobj.get_data());
                                //this.insertData(nobj.get_data());
                            }
                            nobj = null;

                        }), 13);
                        break;
                    case 'cancelupdate':
                        nobj = null;
                        prnNode.removeChild(newEl);
                        break;
                }
            }));
        }

        // private members that not published
        function Batik$UI$DataView$_showProgress() {
            var progTemplate = Batik$UI$DataView$get_progressTemplate.apply(this, []);
            if (!!progTemplate) {
                Sys.UI.DomElement.setVisible(progTemplate, true);
                var childs = progTemplate.getElementsByTagName('*');
                for (var i = 0; i < childs.length; i++) {
                    if (!!childs[i].style) {
                        Sys.UI.DomElement.setVisible(childs[i], true);
                    }
                }
            }
        }

        function Batik$UI$DataView$_onItemRendering(sender, args) {
            if (this._enablePaging && (Math.floor(Array.indexOf(sender.get_data(), args.get_dataItem(), 0) / this._pageSize) !== this._currentPageIndex)) {
                args.set_itemTemplate(null);
            }
        }
        function Batik$UI$DataView$_onRendering(sender, e) {
            Batik$UI$DataView$_showProgress.apply(this, []);
        }
        function Batik$UI$DataView$_onRendered(sender, e) {
            var progTemplate = this.get_progressTemplate();
            if (!!progTemplate) {
                Sys.UI.DomElement.setVisible(progTemplate, false);
            }
        }
        function Batik$UI$DataView$_onSelectComplete(sender, args) {
            // Make the data collection 'observable'
            var data = args.get_data();
            Sys.Observer.makeObservable(data);
            var totalPage = Math.ceil(data.length / this._pageSize);
            var pages = [];
            for (var i = 0; i < totalPage; i++) {
                pages.push({ pageIndex: i, pageNumber: i + 1 });
            }
            var nav = $create(Sys.UI.DataView,
                    { "autoFetch": true, "data": pages, "id": String.format('{0}_PageNavigator', this.id),
                        itemTemplate: $get('pageNavigatorTemplate'),
                        itemPlaceholder: $get('itemPlaceholder')
                    }, null, null, $get('pageNavigator'));
            nav.add_command(Function.createDelegate(this, function(s, e) {
                switch (e.get_commandName()) {
                    case 'select':
                        this._currentPageIndex = e.get_commandArgument() * 1;
                        this.refresh();
                        break;
                    case 'first-page':
                        this._currentPageIndex = 0;
                        this.refresh();
                        break;
                    case 'previous-page':
                        if (this._currentPageIndex > 0) {
                            this._currentPageIndex--;
                            this.refresh();
                        }
                        break;
                    case 'next-page':
                        var lastPageIndex = (Math.ceil(this.get_data().length / this._pageSize)) - 1;
                        if (this._currentPageIndex < lastPageIndex) {
                            this._currentPageIndex++;
                            this.refresh();
                        }
                        break;
                    case 'last-page':
                        var lastPageIndex = (Math.ceil(this.get_data().length / this._pageSize)) - 1;
                        this._currentPageIndex = lastPageIndex;
                        this.refresh();
                        break;
                }
            }));
            this.set_data(data);
        }

        function Batik$UI$DataView$_onCommand(sender, args) {
            var context = this.findContext(args.get_commandSource());
            var prevSelectedIndex = sender.get_selectedIndex();
            if (prevSelectedIndex >= 0 && prevSelectedIndex != context.index) {
                var prevContext = sender.get_contexts()[prevSelectedIndex];
                prevContext.nodes[0].style.display = '';
                prevContext.nodes[0].style.visibility = 'visible';
                if (prevContext.nodes.length > 1) {
                    prevContext.nodes[1].style.display = 'none';
                    prevContext.nodes[1].style.visibility = 'hidden';
                }

                for (var i = 0; i < prevContext.nodes.length; i++) {
                    prevContext.nodes[i].className = 'row';
                }
            }

            for (var i = 0; i < context.nodes.length; i++) {
                context.nodes[i].className = 'selected-row';
            }

            switch (args.get_commandName()) {
                case 'delete':
                    if (confirm('Are you sure want to delete selected data?')) {
                        var deletedItem = context.dataItem;
                        //if (source.get_data().remove(deletedItem)) {
                        if (sender._data.remove(deletedItem)) {
                            var _datasource = this.get_datasource();
                            if (_datasource) {
                                _datasource.deleteData(deletedItem);
                            }
                        }
                    }
                    break;
                case 'edit':
                    Batik$UI$DataView$_set_editMode.apply(this, [true, context.nodes[0], context.nodes[1]]);
                    Sys.Observer.beginUpdate(context.dataItem);
                    break;
                case 'update':
                    if (confirm('Are you sure want to update selected data?')) {
                        Batik$UI$DataView$_set_editMode.apply(this, [false, context.nodes[0], context.nodes[1]]);
                        Batik$UI$DataView$_updateData.apply(this, [context.dataItem]);
                        Sys.Observer.endUpdate(context.dataItem);
                    }
                    break;
                case 'cancelupdate':
                    Batik$UI$DataView$_set_editMode(false, context.nodes[0], context.nodes[1]);
                    for (var i = 0; i < context.nodes[1].children.length; i++) {
                        if (context.nodes[1].children[i].children[0].tagName == 'INPUT') {
                            context.nodes[1].children[i].children[0].value = context.nodes[0].children[i].innerText;
                        }
                    }
                    /// TODO: Please fix it: cancel method does not working properly when endUpdate method is executed
                    //Sys.Observer.endUpdate(context.dataItem);
                    break;
            }
        }

        function Batik$UI$DataView$_updateData(dataItem) {
            var _ds = this.get_datasource();
            if (_ds) {
                _ds.updateData(dataItem);
            }
        }
        function Batik$UI$DataView$_set_editMode(isEditMode, viewElement, editElement, dataItem) {
            if (!!viewElement) {
                Sys.UI.DomElement.setVisible(viewElement, !isEditMode);
            }
            if (!!editElement) {
                Sys.UI.DomElement.setVisible(editElement, isEditMode);
                var elms = editElement.getElementsByTagName('input');
                for (var i = 0; i < elms.length; i++) {
                    var att = elms[i].getAttribute('type');
                    if ((!!att) && att.toLowerCase() === 'text') {
                        try {
                            elms[i].focus();
                        }
                        catch (e) { };
                        break;
                    }
                }
            }
            this._editMode = isEditMode;
        }
        function Batik$UI$DataView$_get_editMode() {
            return this._editMode;
        }

        Batik.UI.DataView.prototype = {
            initialize: Batik$UI$DataView$initialize,
            dispose: Batik$UI$DataView$dispose,
            set_datasourceID: Batik$UI$DataView$set_datasourceID,
            get_datasourceID: Batik$UI$DataView$get_datasourceID,
            get_datasource: Batik$UI$DataView$get_datasource,
            set_viewTemplate: Batik$UI$DataView$set_viewTemplate,
            get_viewTemplate: Batik$UI$DataView$get_viewTemplate,
            set_editTemplate: Batik$UI$DataView$set_editTemplate,
            get_editTemplate: Batik$UI$DataView$get_editTemplate,
            set_progressTemplate: Batik$UI$DataView$set_progressTemplate,
            get_progressTemplate: Batik$UI$DataView$get_progressTemplate,
            insert: Batik$UI$DataView$insert
        }

        Batik.UI.DataView.registerClass("Batik.UI.DataView", Sys.UI.DataView);

        if (!Sys.converters.dateToString) {
            Sys.converters.dateToString = function(value, binding) {
                if (!!value) {
                    if (binding.dateFormat) {
                        return value.format(binding.dateFormat);
                    } else {
                        return value.format(Sys.CultureInfo.CurrentCulture.dateTimeFormat.LongDatePattern);
                    }
                }
            }
        }
    }

    if (window.Sys && Sys.loader) {
        Sys.loader.registerScript("BatikDataView", null, execute);
    }
    else {
        execute();
    }

})();

